﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.IO;
using System.Web.Caching;
using System.ComponentModel;
using System.Web.UI.WebControls.WebParts;

namespace JQuery.Net.Controls
{
    /// <summary>
    /// This Control will be used to configure any global settings that can and eventualy will be set that will affect how
    /// the JQuery API Library will behave.
    /// </summary>
    [ToolboxData("<{0}:Global runat=server></{0}:Global>")]
    [ParseChildren(true), PersistChildren(false)]
    public class Global
        : Control,
        IjQNetAPI
    {
        private int tabs = 0;

        #region contructors
        public Global()
            : base()
        {
            /// we do not need the view state for this control
            EnableViewState = false;
        }
        #endregion

        #region page events
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            /// in this situation we want to validate that the page contains only one instance of this control.
            /// if there was more than one it could lead to un-expected results.
            if (Page.Controls.ByInterface<IjQNetAPI>().Where((X) =>
                X.GetType() == typeof(Global)).Count() > 1)
            {   /// in this case the page contains more than one instance of the global jquery control
                throw new InvalidOperationException(String.Format("Only one instance of the JQuery.Net Control '{0}' should exist on this page.", GetType().Name));
            }
        }
        #endregion

        #region control properties
        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),

        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public AjaxConfig AjaxSetup { get; set; }
        #endregion

        #region IJQueryControl Members
        /// <summary>
        /// 
        /// </summary>
        /// <param name="manager"></param>
        /// <param name="options"></param>
        /// <remarks>
        /// in this case we are going to build and register a cached javascript document that will 
        /// initialize the Global Defaults for the JQuery API
        /// </remarks>
        public void RegisterScriptIncludes(JQNRegistration register)
        {
            // it no longer makes sense to generate individual inlcude files for configuration info that could be particular to one page only.
        }

        private void WriteTabs(StringWriter oWriter)
        {
            for (int x = 0; x < tabs; x++)
                oWriter.Write("\t");
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        public void RegisterStartupScript(StringWriter oStartup)
        {
            StringBuilder oScript = new StringBuilder();

            using (StringWriter oWriter = new StringWriter(oScript))
            {
                oWriter.WriteLine(@"/// Global Settings Injected by the '{0}'.", GetType().FullName);

                oWriter.WriteLine("$.ajaxSetup({");

                tabs += 1;

                if (AjaxSetup.Url.IsNotNullOrEmpty())
                {
                    WriteTabs(oWriter);
                    oWriter.WriteLine("url: {0},", AjaxSetup.Url.StartsWith("~")
                        ? Page.ResolveUrl(AjaxSetup.Url).ToJSON()
                        : AjaxSetup.Url.ToJSON());
                }

                if (AjaxSetup.RequestType.HasValue)
                {
                    WriteTabs(oWriter);
                    oWriter.WriteLine("type: {0}", Enum.GetName(AjaxSetup.RequestType.Value.GetType(), AjaxSetup.RequestType.Value).ToJSON());
                }

                if (AjaxSetup.DataTypes.HasValue)
                {
                    WriteTabs(oWriter);
                    oWriter.WriteLine("dataType: {0}", Enum.GetName(AjaxSetup.DataTypes.Value.GetType(), AjaxSetup.DataTypes.Value).ToJSON());
                }

                //if (AjaxSetup.Accepts.IsNotNullOrEmpty())
                //{
                //    WriteTabs(oWriter);
                //    oWriter.WriteLine("accepts: {0},", AjaxSetup.Accepts.ToJSON());
                //}

                if (AjaxSetup.Async.HasValue)
                {

                    WriteTabs(oWriter);
                    oWriter.WriteLine("async: {0},", AjaxSetup.Async.Value.ToJSON());
                }

                if (AjaxSetup.Cache.HasValue)
                {
                    WriteTabs(oWriter);
                    oWriter.WriteLine("cache: {0},", AjaxSetup.Cache.Value.ToJSON());
                }

                if (AjaxSetup.CrossDomain.HasValue)
                {
                    WriteTabs(oWriter);
                    oWriter.WriteLine("crossDomain: {0},", AjaxSetup.CrossDomain.Value.ToJSON());
                }

                if (AjaxSetup.Global.HasValue)
                {
                    WriteTabs(oWriter);
                    oWriter.WriteLine("global: {0},", AjaxSetup.Global.Value.ToJSON());
                }

                if (AjaxSetup.IfModified.HasValue)
                {
                    WriteTabs(oWriter);
                    oWriter.WriteLine("ifModified: {0},", AjaxSetup.IfModified.Value.ToJSON());
                }

                if (AjaxSetup.UserName.IsNotNullOrEmpty())
                {
                    WriteTabs(oWriter);
                    oWriter.WriteLine("username: {0},", AjaxSetup.UserName.ToJSON());
                }

                if (AjaxSetup.Password.IsNotNullOrEmpty())
                {
                    WriteTabs(oWriter);
                    oWriter.WriteLine("password: {0},", AjaxSetup.Password.ToJSON());
                }

                tabs -= 1;

                oScript.Remove(oScript.ToString().LastIndexOf(','), 1); /// this should remove the last comma
                /// this is necessary for compatability with IE7 and older
                oWriter.WriteLine("});\r\n");
                oWriter.WriteLine("///  Finished Generating Global Settings.\r\n\r\n");
            }

            oStartup.WriteLine(oScript);
        }


        #endregion
    }
}
